#include <bits/stdc++.h>

using namespace std;

const int MAXN = 910;
const int inf = 0x3f3f3f3f;

typedef struct {int v,w,nxt;} edge;

int n,m,a[35][35],h[MAXN],now[MAXN],d[MAXN],cnt = 1,tot,maxflow,s,t;
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};
edge e[MAXN<<3];

void link(int x,int y,int w){
	e[++cnt] = edge{y,w,h[x]};h[x] = cnt;
	e[++cnt] = edge{x,0,h[y]};h[y] = cnt;
}

int id(int x,int y){return (x-1)*n+y;}

bool bfs(){
	memset(d,0,sizeof(d));
	now[s] = h[s];d[s] = 1;
	queue<int> q;
	q.push(s);
	while(q.size()){
		int x = q.front();q.pop();
		for(int i = h[x];i;i = e[i].nxt){
			int y = e[i].v;
			if(!d[y] && e[i].w){
				d[y] = d[x] + 1;
				now[y] = h[y];
				q.push(y);
				if(y == t) return 1;
			}
		}
	}
	return 0;
}

int dinic(int x,int flow){
	if(x == t) return flow;
	int res = flow;
	for(int i = now[x];res && i;i = e[i].nxt){
		int y = e[i].v;now[x] = i;
		if(d[y] == d[x] + 1 && e[i].w){
			int k = dinic(y,min(e[i].w,res));
			if(!k) d[y] = 0;
			e[i].w -= k;
			e[i^1].w += k;
			res -= k;
		}
	}
	return flow - res;
}

int main (){
	scanf("%d %d",&m,&n);
	s = 0,t = m*n+1;
	for(int i = 1;i <= m;i++)
		for(int j = 1;j <= n;j++){
			scanf("%d",&a[i][j]);
			if(i + j & 1) link(id(i,j),t,a[i][j]);
			else link(s,id(i,j),a[i][j]);
			tot+=a[i][j];
		}
	for(int i = 1;i <= m;i++)
		for(int j = i & 1 ? 1 : 2;j<=n;j+=2){
			int p = id(i,j);
			for(int k = 0;k < 4;k++){
				int ni = i + dx[k],nj = j + dy[k];
				if(ni && nj && ni <= m && nj <= n){
					int pp = id(ni,nj);
					link(p,pp,inf);
				}
			}
		}
	int flow = 0;
	while(bfs()) while(flow = dinic(s,inf)) maxflow += flow;
	printf("%d\n",tot-maxflow);
	return 0;
}
